﻿using MongoDB.Bson;
using MongoDB.Driver;
using Sustainalytics.DataLayer.Shared;
using Sustainalytics.ESG.Entities;
using Sustainalytics.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Sustainalytics.DataLayer.EsgRatings
{
    public class StandardIndicatorsRepository : RepositoryCollection<RPIndicatorExtended>, IStandardIndicatorsRepository
    {
        public StandardIndicatorsRepository(string mongoDbUrl)
            : base(mongoDbUrl, typeof(RPIndicatorExtended).Name)
        {
        }

        public IList<RPIndicatorExtended> ReadAllWhere(
            Guid companyId,
            Guid themeId,
            string clusterName = null,
            int? skip = null,
            int? take = null,
            Ordering<RPIndicatorExtended> ordering = null,
            params Expression<Func<RPIndicatorExtended, object>>[] includeFields)
        {
            Expression<Func<RPControversyIndicator, object>> expression1 = x => x.CompanyId;
            Expression<Func<RPControversyIndicator, object>> expression2 = x => x.Template.ThemeId;
            Expression<Func<RPControversyIndicator, object>> expression3 = x => x.Template.IndicatorCategory;
            var query = Builders<RPIndicatorExtended>.Filter.And(
                Builders<RPIndicatorExtended>.Filter.Eq(expression1.GetPropertyName(), BsonValue.Create(companyId)),
                Builders<RPIndicatorExtended>.Filter.Eq(expression2.GetPropertyName(), BsonValue.Create(themeId)));

            if (!clusterName.IsNullOrEmpty())
            {
                query = Builders<RPIndicatorExtended>.Filter.And(query, Builders<RPIndicatorExtended>.Filter.Eq(expression3.GetPropertyName(), BsonValue.Create(clusterName)));
            }

            var cursor = Collection().Find(query);
            if (skip != null)
            {
                cursor = cursor.Skip(skip.Value);
            }

            if (take != null)
            {
                cursor = cursor.Limit(take.Value);
            }

            if (ordering != null)
            {
                cursor = cursor.Sort(ordering.ToMongoSortBy());
            }

            if (includeFields != null && includeFields.Any())
            {
                cursor = cursor.Project<RPIndicatorExtended>(Builders<RPIndicatorExtended>.Projection.Include(includeFields.Select(x => x.GetPropertyName()).ToArray()));
            }

            return cursor.ToList();
        }
    }
}
